import { Injectable } from '@nestjs/common';
import { v4 as uuidv4, parse as uuidParse } from 'uuid';
import { InjectModel } from '@nestjs/sequelize';
import * as moment from 'moment';
import * as fs from 'fs';
import * as path from 'path';
import { BaseService } from 'src/logical/common/services/base.service';
import { AccessoryEntity } from '../entity/accessory.entity';
import { AccessoryModel } from '../models/accessory.model';
import constantConfig from 'config/constant';

const imgSuffix = ['.png', '.jpg', '.jpeg', '.gif', '.bmp'];
const videoSuffix = [
  '.flv',
  '.swf',
  '.mkv',
  '.avi',
  '.rm',
  '.rmvb',
  '.mpeg',
  '.mpg',
  '.ogg',
  '.ogv',
  '.mov',
  '.wmv',
  '.mp4',
  '.webm',
  '.mp3',
  '.wav',
  '.mid',
];
const docSuffix = [
  '.doc',
  '.docx',
  '.xls',
  '.xlsx',
  '.ppt',
  '.pptx',
  '.pdf',
  '.txt',
  '.md',
  '.xml',
];
@Injectable()
export class AccessoryService extends BaseService {
  constructor(
    @InjectModel(AccessoryEntity)
    private accessoryEntityModel: typeof AccessoryEntity,
  ) {
    super();
  }

  mkdirsSync(dirname) {
    if (fs.existsSync(dirname)) {
      return true;
    } else {
      if (this.mkdirsSync(path.dirname(dirname))) {
        fs.mkdirSync(dirname);
        return true;
      }
    }
  }
  saveFile(filePath, fileData) {
    return new Promise((resolve, reject) => {
      // 块方式写入文件
      const wstream = fs.createWriteStream(filePath);
      wstream.on('open', () => {
        const blockSize = 128;
        const nbBlocks = Math.ceil(fileData.length / blockSize);
        for (let i = 0; i < nbBlocks; i += 1) {
          const currentBlock = fileData.slice(
            blockSize * i,
            Math.min(blockSize * (i + 1), fileData.length),
          );
          wstream.write(currentBlock);
        }
        wstream.end();
      });
      wstream.on('error', (err) => {
        reject(err);
      });
      wstream.on('finish', () => {
        resolve(true);
      });
    });
  }
  async accessoryUpload(file: Express.Multer.File, tokenInfo) {
    const res = new AccessoryModel();

    let uploadPath: string = 'testupload/';

    if (!file) {
      return this.resultData(null, 500, '不能上传空文件');
    }

    let fileName: string = file.originalname;
    let suffixName: string = fileName
      .substring(fileName.lastIndexOf('.'))
      .toLowerCase();

    console.log(suffixName);

    if (imgSuffix.indexOf(suffixName) > -1) {
      const suffixPath: string =
        'image/' + moment(this.getNowDate()).format('yyyyMMDD');
      uploadPath =
        uploadPath.charAt(uploadPath.length - 1) === '/'
          ? uploadPath + suffixPath
          : uploadPath + '/' + suffixPath;
    } else if (videoSuffix.indexOf(suffixName) > -1) {
      const suffixPath: string =
        'video/' + moment(this.getNowDate()).format('yyyyMMDD');
      uploadPath =
        uploadPath.charAt(uploadPath.length - 1) === '/'
          ? uploadPath + suffixPath
          : uploadPath + '/' + suffixPath;
    } else if (docSuffix.indexOf(suffixName) > -1) {
      const suffixPath: string =
        'doc/' + moment(this.getNowDate()).format('yyyyMMDD');
      uploadPath =
        uploadPath.charAt(uploadPath.length - 1) === '/'
          ? uploadPath + suffixPath
          : uploadPath + '/' + suffixPath;
    } else {
      const suffixPath: string =
        'others/' + moment(this.getNowDate()).format('yyyyMMDD');
      uploadPath =
        uploadPath.charAt(uploadPath.length - 1) === '/'
          ? uploadPath + suffixPath
          : uploadPath + '/' + suffixPath;
    }

    const newFileName: string = uuidv4().replace(/-/g, '');
    const filePath: string =
      constantConfig.upload_path.charAt(
        constantConfig.upload_path.length - 1,
      ) === '/'
        ? constantConfig.upload_path + uploadPath
        : constantConfig.upload_path + '/' + uploadPath;

    res.fileName = newFileName;
    res.suffixName = suffixName;
    const size: string = String((file.size / 1024).toFixed(2));
    res.size = size + 'KB';
    res.createDate = this.getNowDate();
    res.creatorId = tokenInfo.accountId;

    if (constantConfig.accessory_local_storage) {
      const folderPath = path.resolve(process.cwd(), filePath);
      console.log(folderPath);
      console.log(fs.existsSync(folderPath));

      if (!fs.existsSync(folderPath)) {
        this.mkdirsSync(folderPath);
      }
      const dest = path.resolve(
        process.cwd(),
        filePath + '/' + newFileName + suffixName,
      );
      await this.saveFile(dest, file.buffer);
    }

    const accessoryEntity = new AccessoryEntity();
    for (const key in res) {
      if (Object.prototype.hasOwnProperty.call(res, key)) {
        accessoryEntity[key] = res[key];
      }
    }
    accessoryEntity.id = this.nextId();
    if (constantConfig.accessory_db_storage) {
      accessoryEntity.detail = file.buffer;
    }
    accessoryEntity.save();

    return this.getSuccessResultData(res);
  }
}
